/*
 * Copyright (C) 2013 Mestrelab Research S.L. All rights reserved.
 *
 * This file is part of the Mnova scripting toolkit.
 *
 * Authorized users of MNova Software may use this file freely, but this file is provided AS IS
 * with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE.
 */

/*jslint plusplus: true, indent: 4*/
/*global Application, qsTr, print, mainWindow, NMRSpectrum, Page, NMRArithmetic, nmr, MessageBox, MnUi*/

function DEPTImporter() {
	'use strict';
	this.importedItem = null;
	this.resultArrayedItem = null;
}

DEPTImporter.prototype = {
	processDEPT: function () {
		'use strict';
		var importSpcCount,
			arith = new NMRArithmetic(),
			chSpc,
			ch2Spc,
			ch3Spc,
			chAllSpc,
			resultArr = [],
			pagesToBeRemoved = [];

		if (this.importedItem && this.importedItem.isValid()) {
			importSpcCount = this.importedItem.specCount;
			mainWindow.setBusy(qsTr('Processing'));

			switch (importSpcCount) {
			case 3:
			//0 dept45, 1 dept90, 2 dept135
				chSpc = nmr.extractSpectrumFromArrayedItem(this.importedItem, 0);
				chSpc.comment = 'CH';
				chSpc.experimentType = "1D-EDITED-CH";
				ch2Spc = nmr.extractSpectrumFromArrayedItem(this.importedItem, 1);
				ch2Spc.comment = 'CH2';
				ch2Spc.experimentType = "1D-EDITED-CH2";
				ch3Spc = nmr.extractSpectrumFromArrayedItem(this.importedItem, 2);
				ch3Spc.comment = 'CH3';
				ch3Spc.experimentType = "1D-EDITED-CH3";
				chAllSpc = nmr.extractSpectrumFromArrayedItem(this.importedItem, 3);
				chAllSpc.comment = 'CH All';
				chAllSpc.experimentType = "1D";
				pagesToBeRemoved.push(chSpc.page.uuid, ch2Spc.page.uuid, ch3Spc.page.uuid, chAllSpc.page.uuid);
				resultArr.push(chAllSpc, chSpc, ch2Spc, ch3Spc);

				arith.spectraList.push({item: this.importedItem, index: 0, id: 'dept45'});
				arith.spectraList.push({item: this.importedItem, index: 1, id: 'dept90'});
				arith.spectraList.push({item: this.importedItem, index: 2, id: 'dept135'});
				arith.spectraList.push({item: chSpc, id: 'ch'});
				arith.spectraList.push({item: ch2Spc, id: 'ch2'});
				arith.spectraList.push({item: ch3Spc, id: 'ch3'});
				arith.spectraList.push({item: chAllSpc, id: 'chAll'});

				//VNMR Liquids User Guide
				arith.runFormula('dept90', 'ch');
				arith.runFormula('dept45 - dept135', 'ch2');
				arith.runFormula('dept45 + dept135 - 0.77*dept45 - 0.77*dept90', 'ch3');
				arith.runFormula('0.23*(dept45 + dept90) + 2*dept45', 'chAll');

				//arith.applyThreshold1D(chSpc.realMax/thrFactor, chSpc, chSpc);
				arith.clearNegativePeaks(chSpc, chSpc);
				//arith.applyThreshold1D(ch2Spc.realMax/thrFactor, ch2Spc, ch2Spc);
				arith.clearNegativePeaks(ch2Spc, ch2Spc);
				//arith.applyThreshold1D(ch3Spc.realMax/thrFactor, ch3Spc, ch3Spc);
				arith.clearNegativePeaks(ch3Spc, ch3Spc);
				break;
			case 4:
			//0 dept45, 1 dept90, 2 dept90, 3 dept135
				chSpc = nmr.extractSpectrumFromArrayedItem(this.importedItem, 0);
				chSpc.comment = 'CH';
				chSpc.experimentType = "1D-EDITED-CH";
				ch2Spc = nmr.extractSpectrumFromArrayedItem(this.importedItem, 1);
				ch2Spc.comment = 'CH2';
				ch2Spc.experimentType = "1D-EDITED-CH2";
				ch3Spc = nmr.extractSpectrumFromArrayedItem(this.importedItem, 2);
				ch3Spc.comment = 'CH3';
				ch3Spc.experimentType = "1D-EDITED-CH3";
				chAllSpc = nmr.extractSpectrumFromArrayedItem(this.importedItem, 3);
				chAllSpc.comment = 'CH All';
				chAllSpc.experimentType = "1D";
				pagesToBeRemoved.push(chSpc.page.uuid, ch2Spc.page.uuid, ch3Spc.page.uuid, chAllSpc.page.uuid);
				resultArr.push(chAllSpc, chSpc, ch2Spc, ch3Spc);

				arith.spectraList.push({item: this.importedItem, index: 0, id: 'dept45'});
				arith.spectraList.push({item: this.importedItem, index: 1, id: 'dept90_1'});
				arith.spectraList.push({item: this.importedItem, index: 2, id: 'dept90_2'});
				arith.spectraList.push({item: this.importedItem, index: 3, id: 'dept135'});
				arith.spectraList.push({item: chSpc, id: 'ch'});
				arith.spectraList.push({item: ch2Spc, id: 'ch2'});
				arith.spectraList.push({item: ch3Spc, id: 'ch3'});
				arith.spectraList.push({item: chAllSpc, id: 'chAll'});

				//VNMR Liquids User Guide
				arith.runFormula('dept90_1 + dept90_2', 'ch');
				arith.runFormula('dept45 - dept135', 'ch2');
				arith.runFormula('dept45 + dept135 - 0.77*dept45 - 0.77*dept90_2', 'ch3');
				arith.runFormula('0.23*(dept45 + dept90_1) + 2*dept45', 'chAll');

				//arith.applyThreshold1D(chSpc.realMax/thrFactor, chSpc, chSpc);
				arith.clearNegativePeaks(chSpc, chSpc);
				//arith.applyThreshold1D(ch2Spc.realMax/thrFactor, ch2Spc, ch2Spc);
				arith.clearNegativePeaks(ch2Spc, ch2Spc);
				//arith.applyThreshold1D(ch3Spc.realMax/thrFactor, ch3Spc, ch3Spc);
				arith.clearNegativePeaks(ch3Spc, ch3Spc);
				break;
			default:
				break;
			}

			if (resultArr.length) {
				this.resultArrayedItem = nmr.createArrayedItem(resultArr, true);
				//this.resultArrayedItem.fitToHeight();
				pagesToBeRemoved.push(this.importedItem.page.uuid);
			}
			mainWindow.activeDocument.deletePages(pagesToBeRemoved);
			mainWindow.endBusy();
			return true;
		}
		return false;
	},

	processDEPTq: function () {
		'use strict';
		var importSpcCount,
			arith = new NMRArithmetic(),
			resultArr = [],
			pagesToBeRemoved = [],
			cAll,
			cQ,
			cH,
			cH2,
			cH3,
			ch3scaleFactor = 0.707,
			scaleFactor = 0.25,
			dummy;

		if (this.importedItem && this.importedItem.isValid()) {
			importSpcCount = this.importedItem.specCount;
			if (importSpcCount === 8) {
				mainWindow.setBusy(qsTr('Processing'));
				//All
				cAll = nmr.extractSpectrumFromArrayedItem(this.importedItem, 0);//All
				pagesToBeRemoved.push(cAll.page.uuid);
				cAll.comment = 'All';
				cAll.experimentType = "1D";

				//Only Cq: 0 - 1 + 2 - 3 + 4 - 5 + 6 - 7
				cQ = nmr.extractSpectrumFromArrayedItem(this.importedItem, 0);
				pagesToBeRemoved.push(cQ.page.uuid);
				cQ.comment = "Cq";
				cQ.experimentType = "1D-EDITED-CQ";
				arith.sub(cQ, this.importedItem, 1, cQ);
				arith.add(cQ, this.importedItem, 2, cQ);
				arith.sub(cQ, this.importedItem, 3, cQ);
				arith.add(cQ, this.importedItem, 4, cQ);
				arith.sub(cQ, this.importedItem, 5, cQ);
				arith.add(cQ, this.importedItem, 6, cQ);
				arith.sub(cQ, this.importedItem, 7, cQ);

				//Only CH = 2 + 3 + 4 +5
				cH = nmr.extractSpectrumFromArrayedItem(this.importedItem, 2);
				cH.comment = "CH";
				cH.experimentType = "1D-EDITED-CH";
				pagesToBeRemoved.push(cH.page.uuid);
				arith.add(cH, this.importedItem, 3, cH);
				arith.add(cH, this.importedItem, 4, cH);
				arith.add(cH, this.importedItem, 5, cH);

				// CH3only 0 + 1 + 6 + 7 - ch3scaleFactor*(2 + 3 + 4 + 5)
				cH3 = nmr.extractSpectrumFromArrayedItem(this.importedItem, 3);
				pagesToBeRemoved.push(cH3.page.uuid);
				cH3.comment = "CH3 " + ch3scaleFactor;
				cH3.experimentType = "1D-EDITED-CH3";
				arith.add(cH3, this.importedItem, 2, cH3);
				arith.add(cH3, this.importedItem, 4, cH3);
				arith.add(cH3, this.importedItem, 5, cH3);
				arith.scale(ch3scaleFactor, cH3, cH3);
				arith.sub(this.importedItem, 0, cH3, cH3);
				arith.add(cH3, this.importedItem, 1, cH3);
				arith.add(cH3, this.importedItem, 6, cH3);
				arith.add(cH3, this.importedItem, 7, cH3);
				arith.clearNegativePeaks(cH3, cH3);

				//Only CH2 = 0 + 1 - 6 - 7 - scaleFactor*CH3Only
				cH2 = nmr.extractSpectrumFromArrayedItem(this.importedItem, 4);
				pagesToBeRemoved.push(cH2.page.uuid);
				cH2.comment = "CH2";
				cH2.experimentType = "1D-EDITED-CH2";
				arith.scale(scaleFactor, cH3, cH2);
				dummy = nmr.extractSpectrumFromArrayedItem(this.importedItem, 0);
				pagesToBeRemoved.push(dummy.page.uuid);
				arith.add(dummy, this.importedItem, 1, dummy);
				arith.sub(dummy, this.importedItem, 6, dummy);
				arith.sub(dummy, this.importedItem, 7, dummy);
				arith.sub(dummy, cH2, cH2);
				arith.clearNegativePeaks(cH2, cH2);

				resultArr.push(cAll);
				arith.scale(0.125, cQ, cQ);
				resultArr.push(cQ);
				arith.scale(0.25, cH, cH);
				resultArr.push(cH);
				arith.scale(0.25, cH2, cH2);
				resultArr.push(cH2);
				arith.scale(0.25, cH3, cH3);
				resultArr.push(cH3);

				if (resultArr.length) {
					this.resultArrayedItem = nmr.createArrayedItem(resultArr, true);
					//this.resultArrayedItem.fitToHeight();
					pagesToBeRemoved.push(this.importedItem.page.uuid);
				}
				mainWindow.activeDocument.deletePages(pagesToBeRemoved);
				mainWindow.endBusy();
				return true;
			}
		}
	},

	process: function (aSpec) {
		'use strict';
		if (aSpec && aSpec.isValid() && aSpec.name === 'NMR Spectrum') {
			this.importedItem = aSpec;
			switch (this.importedItem.specCount) {
			case 3:
			case 4:
				return this.processDEPT();
			case 8:
				return this.processDEPTq();
			default:
				break;
			}
		}
		this.importedItem = null;
		return false;
	},

	wantsToProcess: function (aSpec) {
		'use strict';
		return aSpec && aSpec.isValid() && (aSpec.specCount === 3 || aSpec.specCount === 4 || aSpec.specCount === 8) && aSpec.experimentType.match(/DEPT|dept/) && aSpec.originalFormat === 'Varian';
	},

	rejectedMessage: function (aSpecs) {
		'use strict';
		var processedVarian, i, spec, message;

		processedVarian = false;
		for (i = 0; i < aSpecs.specCount; i++) {
			spec = aSpecs.spectra[i];
			if ((((spec.experimentType === "1D-EDITED-CQ") && (spec.comment.indexOf("Cq") >= 0)) ||
				((spec.experimentType === "1D-EDITED-CH") && (spec.comment.indexOf("CH") >= 0))) && (spec.originalFormat === 'Varian')) {
				processedVarian = true;
				break;
			}
		}
		if (processedVarian) {
			message = qsTr("Dataset cannot be processed. It appears that the DEPT dataset has been already processed during the import. Check Preferences-NMR-Import for the option to process Varian DEPT");
		} else {
			message = qsTr("Dataset is not compatible with DEPT processing");
		}
		MessageBox.critical(message);
	}
};

function DEPT() {
	'use strict';
	var deptImport = new DEPTImporter(),
		document = mainWindow.activeDocument,
		page = new Page(document.curPage()),
		spec = new NMRSpectrum(page.item(0, 'NMR Spectrum'));

	if (deptImport.wantsToProcess(spec)) {
		deptImport.process(spec);
	} else {
		deptImport.rejectedMessage(spec);
	}
}

DEPT.onDEPTImported = function (aJSONString) {
	"use strict";

	var info = JSON.parse(aJSONString),
		actDoc = mainWindow.activeDocument,
		spec = actDoc.getItem(info.itemId),
		deptImport = new DEPTImporter();

	if (spec.name === "NMR Spectrum") {
		spec = new NMRSpectrum(spec);
		if (deptImport.wantsToProcess(spec)) {
			deptImport.process(spec);
			return true;
		}
	}
	return false;
};

//if (Application.mainWindow) {
	//Application.mainWindow.installEventHandler("nmrSpectrumImported", "DEPT.onDEPTImported");
//}

if (this.MnUi && MnUi.scripts_nmr) {
	MnUi.scripts_nmr.scripts_nmr_DEPTTraces = DEPT;
}
